Python实现动态规划Labeling算法求解SPPRC问题

您所在的位置:网站首页 动态规划 python Python实现动态规划Labeling算法求解SPPRC问题

Python实现动态规划Labeling算法求解SPPRC问题

#Python实现动态规划Labeling算法求解SPPRC问题| 来源: 网络整理| 查看: 265

Python实现一种Labeling算法求解SPPRC问题 SPPRC问题 Labeling算法 Python编程实现 首先在python中对该图进行定义: 创建Label类 调用labeling算法计算

本文中的课件来自清华大学深圳国际研究生院,物流与交通学部戚铭尧教授《物流地理信息系统》课程。

SPPRC问题

  带资源约束的最短路径问题(shortest path problem with resource constraints)是一个众所周知的NP-Hard问题。 除了作为网络问题直接应用外,SPPRC还用作列生成解决方案方法的基础,用于解决车辆路径规划问题和人员排班问题等。   考虑一个有向图 G = ( N , A ) G = (N,A) G=(N,A), N = { v 1 , v 2 , . . . , v i , . . . , v n } N=\{v_1,v_2,...,v_i,...,v_n\} N={v1​,v2​,...,vi​,...,vn​}表示节点的集合,并且 A = { ( i , j ) ∣ v i ∈ N , v j ∈ N , i ≠ j } A=\{(i,j)|v_i \in N,v_j \in N ,i \ne j\} A={(i,j)∣vi​∈N,vj​∈N,i​=j}表示弧的集合。对于每一段弧 ( i , j ) ∈ A (i,j)\in A (i,j)∈A都有一个非负的权重(vrptw问题中可能为负,需要作特殊处理), c i j c_{ij} cij​和 t i j t_{ij} tij​,表示通过这段弧的成本和资源消耗。   SPPRC问题包括找到从起始节点 v s ∈ N v_s \in N vs​∈N到结束节点 v t ∈ N v_t \in N vt​∈N的一条路径 P P P,使该路径的总成本最小化,但不超过最大资源消耗 T T T。即使只存在一种资源,SPPRC也是一个NP-Hard。

Labeling算法

  直接求解SPPRC问题是比较困难的,故通常采用一种动态规划的方法: l a b e l   c o r r e c t i o n   a l g o r i t h m label \ correction \ algorithm label correction algorithm算法。 通常我们考虑有 L L L种资源,可能包括时间、最大装载重量、最大装载体积等。   对于每一条从起始节点 v s v_s vs​扩展到点 v i v_i vi​的路径 X p i X_{pi} Xpi​都有一个标签 ( R i , C i ) (R_i,C_i) (Ri​,Ci​)与之相关联。 R i ≡ ( T i 1 , T i 2 , . . . , T i L ) R_i \equiv (T_i^1,T_i^2,...,T_i^ L) Ri​≡(Ti1​,Ti2​,...,TiL​)是路径使用的每L个资源的数量; C i C_i Ci​是 c o s t cost cost。   此外,我们还需要设置一些优超规则,称为 d o m i n a n c e   r u l e dominance\ rule dominance rule,以帮助减少不必要的扩展。令 X p i X_{pi} Xpi​和 X p i ∗ X_{pi}^* Xpi∗​是从 v s v_s vs​扩展到 v i v_i vi​的两条不同的路径,与之关联的标签分别为 ( R i , C i ) (R_i,C_i) (Ri​,Ci​)和 ( R i ∗ , C i ∗ ) (R_i^*,C_i^*) (Ri∗​,Ci∗​)。路径 X p i X_{pi} Xpi​可以 d o m i n a t e s dominates dominates路径 X p i ∗ X_{pi}^* Xpi∗​当且仅当: C i ≤ C i ∗ , T i l ≤ T i l ∗ , ∀   l ∈ ( 1 , . . . , L ) , ( R i , C i ) ≠ ( R i ∗ , C i ∗ ) C_i \le C_i^*,T_i^l\le T_i^{l*} ,\forall \ l \in (1,...,L), (R_i,C_i) \ne (R_i^*,C_i^*) Ci​≤Ci∗​,Til​≤Til∗​,∀ l∈(1,...,L),(Ri​,Ci​)​=(Ri∗​,Ci∗​)

下面介绍一个简单的小例子: 在这里插入图片描述 一个有向图如上图所示,我们可以看到每一段弧上都有一个非负的权重,分别表示通过该弧的 t i m e time time与 c o s t cost cost。首先初始化出发节点 p p p的标签,设置为 [ 0 , 0 ] [0,0] [0,0],随后令其向可达节点 v 2 v_2 v2​和 v 3 v_3 v3​进行扩展,则分别设置一个新的标签 [ 2 , 2 ] [2,2] [2,2]。再由 v 2 v_2 v2​向 v 3 v_3 v3​和 d d d进行扩展,则 v 3 v_3 v3​得到一个新的标签 [ 3 , 0 ] [3,0] [3,0], d d d得到一个新的标签 [ 4 , 4 ] [4,4] [4,4],同理继续扩展到 d d d,生成一个新的标签 [ 5 , 2 ] [5,2] [5,2]。然后回过头由 v 3 v_3 v3​扩展到 v 2 v_2 v2​, v 2 v_2 v2​得到一个新的标签 [ 4 , 1 ] [4,1] [4,1]。我们可以发现没有继续向 d d d扩展了,因为其生成的标签为 [ 6 , 2 ] [6,2] [6,2],与 d d d已有的标签 [ 5 , 2 ] [5,2] [5,2]相比满足了 d o m i n a n c e   r u l e dominance\ rule dominance rule的要求,不必再扩展。

Python编程实现

在这里插入图片描述 考虑这样一个有向图。

首先在python中对该图进行定义: import numpy as np import networkx as nx from time import * # 点中包含时间窗属性 Nodes = {'s': (0, 0) , '1': (6, 14) , '2': (9, 12) , '3': (8, 12) , 't': (9, 15) } # 弧的属性包括travel_time与distance Arcs = {('s','1'): (8, 3) ,('s','2'): (5, 5) ,('s','3'): (12, 2) ,('1','t'): (4, 7) ,('2','t'): (2, 6) ,('3','t'): (4, 3) } # create the directed Graph Graph = nx.DiGraph() cnt = 0 # add nodes into the graph for name in Nodes.keys(): cnt += 1 Graph.add_node(name , time_window = (Nodes[name][0], Nodes[name][1]) , min_dis = 0 ) # add edges into the graph for key in Arcs.keys(): Graph.add_edge(key[0], key[1] , travel_time = Arcs[key][0] , length = Arcs[key][1] ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 创建Label类 class Label: path = [] travel_time = 0 distance = 0 # dominance rule def dominate(Q, Path_set): QCopy = copy.deepcopy(Q) PathsCopy = copy.deepcopy(Path_set) # dominate Q for label in QCopy: for another_label in Q: if (label.path[-1] == another_label.path[ -1] and label.time


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3